package tech.gismap.admin.service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import tech.gismap.admin.web.bo.ChatCompletionRequest;

import java.util.List;
import java.util.Map;

@Service
public class DeepSeekStreamingService {

    @Autowired
    private WebClient webClient;


    public void streamChat(String userPrompt, SseEmitter emitter) {
        ChatCompletionRequest request = new ChatCompletionRequest();
        request.setModel("gemma3:270m");
        request.setStream(true);
        request.setMessages(List.of(
            Map.of("role", "user", "content", userPrompt)
        ));

        webClient.post()
            .uri("/chat/completions")
            .body(BodyInserters.fromValue(request))
            .accept(MediaType.TEXT_EVENT_STREAM)
            .retrieve()
            .bodyToFlux(String.class)
            .doOnNext(chunk -> {
                try {
                    if (chunk.contains("[DONE]")) {
                        emitter.send(SseEmitter.event().data("[DONE]"));
                        emitter.complete();
                    } else {
                        String json = chunk.replaceFirst("data: *", "");
                        String token = parseTokenFromJson(json);
                        emitter.send(SseEmitter.event().data(token));
                    }
                } catch (Exception e) {
                    emitter.completeWithError(e);
                }
            })
            .doOnError(emitter::completeWithError)
            .subscribe();
    }


    private String parseTokenFromJson(String json) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            JsonNode node = mapper.readTree(json);
            return node.path("choices").get(0).path("delta").path("content").asText("");
        } catch (Exception e) {
            return "";
        }
    }
}
